#include "stdafx.h"
#include "kfile.h"

namespace xm 
{
	long volm_file_t::get_win32_full_path( std::string & full )
	{
		if( vol ) 
		{ 
			full = vol->get_dos_name(); 
			full.push_back('\\'); 
		};
		BaseT::get_full_path( full, KoVolume );
		return S_OK;
	}
	
	STDMETHODIMP volm_file_t::MountOn(IKernelObject* k)
	{
		RFAILED( BaseT::MountOn(k) );
		if( !_dir ) return S_OK;
		optr<directory_t> dir = _dir;
		do {
			if( dir->Class() == KoVolume )
			{
				vol = dir->proto<volume_t>();
				break;
			}
			kip_t kip = dir->MountedPlace();
			if( !kip ) break;
			dir = kip->proto<directory_t,KoVolume>();
		} while( dir );
		return S_OK;
	};

	HRESULT volm_file_t::create( IUnknown * kbs, LPCSTR aname, uint32_t opts )
	{
		close();
		if( !kbs || !aname )
			return E_INVALIDARG;
		data = kbs;
		if( !data ) return E_NOINTERFACE;
		if( aname ) set_name( aname );
		opt = opts;
		return S_OK;
	}

	VOID volm_file_t::close()
	{
		opt = 0;
		data.dispose();
	}

	IKBStream * volm_file_t::get_do()
	{
		return data;
	}

	uint32_t volm_file_t::get_opt()
	{
		return opt;
	}
	
	STDMETHODIMP_(BOOL) volm_file_t::IsVirtual() 
	{ 
		return data->IsVirtual(); 
	}

	STDMETHODIMP volm_file_t::Read( LPVOID lpBuffer, SIZE_T cbData, SIZE_T * lpEff )
	{
		return data->Read( lpBuffer, cbData, lpEff );
		//if( !(_Access & (FILE_READ_DATA|GENERIC_READ) ) ) 
		//	return E_ACCESSDENIED;
		//return Readp( ptr, lpBuffer, cbData, lpEff );
	}
	STDMETHODIMP volm_file_t::Write( LPCVOID lpBuffer, SIZE_T cbData, SIZE_T * lpEff )
	{
		return data->Write( lpBuffer, cbData, lpEff );
		//if( !(_Access & (FILE_WRITE_DATA|GENERIC_WRITE)) ) 
		//	return E_ACCESSDENIED;
		//return Writep( ptr, lpBuffer, cbData, lpEff );
	}
	STDMETHODIMP volm_file_t::Seek( INT64 dist, SEEK_FORM from )
	{
		return data->Seek( dist, from );
		//if( from == SEEK_SET )
		//{
		//	ptr = dist;
		//}
		//else if( from == SEEK_CUR )
		//{
		//	ptr += dist;
		//}
		//else if( from == SEEK_END )
		//{
		//	uint64_t fs = data->Length();
		//	if( fs == LENGTH_ERROR ) return E_FAIL;
		//	ptr = fs + dist;
		//}
		//else
		//{
		//	return E_INVALIDARG;
		//}
		//return S_OK;
	}
	STDMETHODIMP volm_file_t::Tell( UINT64 * puliPointer )
	{
		return data->Tell( puliPointer );
		//*puliPointer = ptr;
		//return S_OK;
	}
	STDMETHODIMP volm_file_t::Readp( UINT64 uliPos, LPVOID lpBuffer, SIZE_T cbData, SIZE_T * lpEff )
	{
		return data->Readp( uliPos, lpBuffer, cbData, lpEff );
		//if( !(_Access & FILE_READ_DATA) ) return E_ACCESSDENIED;
		//SIZE_T eff = 0;
		//RFAILED(data->Readp( uliPos, lpBuffer, cbData, &eff ));
		//ptr = uliPos + eff;
		//if( lpEff ) *lpEff = eff;
		//return S_OK;
	}
	STDMETHODIMP volm_file_t::Writep( UINT64 uliPos, LPCVOID lpBuffer, SIZE_T cbData, SIZE_T * lpEff )
	{
		return data->Writep( uliPos, lpBuffer, cbData, lpEff );
		//if( !(_Access & FILE_WRITE_DATA) ) return E_ACCESSDENIED;
		//SIZE_T eff = 0;
		//RFAILED(data->Writep( uliPos, lpBuffer, cbData, &eff ));
		//ptr = uliPos + eff;
		//if( lpEff ) *lpEff = eff;
		//return S_OK;
	}
	STDMETHODIMP volm_file_t::SetPos( UINT64 uliPos )
	{
		return data->SetPos( uliPos );
		//ptr = uliPos;
		//return S_OK;
	}
	STDMETHODIMP_(UINT64) volm_file_t::Length()
	{
		return data->Length();
	}
	STDMETHODIMP volm_file_t::Truncate()
	{
		return data->Truncate();
		//if( !(_Access & FILE_WRITE_DATA) ) return E_ACCESSDENIED;
		//RFAILED( data->Seek( ptr, FROM_BEGIN ) );
		//return data->Truncate();
	}
	STDMETHODIMP volm_file_t::Rollback()
	{
		iptr<IKVirtalFile> vfo( data );
		if( !vfo ) return E_NOTIMPL;
		return vfo->Rollback();
	}
};
